use crate::consts::TaskLen;
use core::sync::atomic::{AtomicUsize, Ordering};
use heapless::Vec;
use spin::Lazy;
use spin::Mutex;
static TASKS: Lazy<Mutex<Vec<Task, TaskLen>>> = Lazy::new(|| Mutex::new(Vec::new()));

static TIME: AtomicUsize = AtomicUsize::new(0);

/// 设置当前时间，单位毫秒
pub fn set(time: usize) {
    TIME.store(time, Ordering::Relaxed);

    for task in TASKS.lock().iter_mut() {
        task.last = time;
    }
}
/// 获取当前时间，单位100毫秒
pub fn get() -> usize {
    TIME.load(Ordering::Relaxed)
}
/// time毫秒执行一次
pub fn tick(time: usize) {
    let time = TIME.fetch_add(time, Ordering::Relaxed);
    let mut tasks = TASKS.lock();
    let mut del_queue = Vec::<usize, TaskLen>::new();
    for i in 0..tasks.len() {
        let task = &mut tasks[i];
        match task.t {
            TaskType::Timeout(t) => {
                if time - task.last < t {
                    continue;
                }
                (task.f)();
                del_queue.push(i).unwrap();
            }
            TaskType::Interval(t) => {
                if time - task.last < t {
                    continue;
                }
                task.last = time;
                (task.f)();
            }
        }
    }
    while let Some(i) = del_queue.pop() {
        tasks.swap_remove(i);
    }
}

pub enum TaskType {
    // n毫秒后执行一次
    Timeout(usize),
    // 每n毫秒执行一次
    Interval(usize),
}
struct Task {
    t: TaskType,
    f: fn() -> (),
    last: usize,
}
pub fn add_task(t: TaskType, f: fn() -> ()) {
    let task = Task {
        t: t,
        f: f,
        last: get(),
    };
    if let Err(_) = TASKS.lock().push(task) {
        panic!("unmp clock task full.");
    }
}
